package com.example.waterfall.util;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import com.example.waterfall.cache.ImageCache;



import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;

/**
 * 图片加载处理
 * 
 * @author huangrongcai
 * 
 */
public abstract class ImageWorker {
	private static final String TAG = "ImageWorker";
	private ImageCache mImageCache;
	protected Context mContext;
	private Bitmap mLoadingBitmap;
	private boolean mExitTasksEarly = true;
	private boolean mPauseTasks = false;
	protected Handler mHandler;
	/**线程池，记录在运行中的线程*/
	private transient Map<ImageView, BitmapWorkerTask> ThreadMap = new HashMap<ImageView, BitmapWorkerTask>();
	protected ImageWorkerAdapter mImageWorkerAdapter;
	//
	public ImageWorker(Context context,Handler handler) {
		this.mContext = context;
		this.mHandler = handler;
	}

	/**
	 * 加载图片
	 * 
	 * @param data 
	 * @param imageView
	 */
	public void loadImage(Object data, ImageView imageView) {
		Bitmap bitmap = null;
		//从缓存加载
		if(mImageCache != null){
			bitmap = mImageCache.get(String.valueOf(data));
		}
		// 从网络加载
		if (bitmap != null) {
			// Bitmap found in memory cache
			setImageBitmap(imageView,bitmap);
		} else if (cancelPotentialWork(data, imageView)) {
			final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
			final AsyncDrawable asyncDrawable = new AsyncDrawable(mContext.getResources(), mLoadingBitmap, task);
			ThreadMap.put(imageView, task);
			if(imageView !=null){
				imageView.setImageDrawable(asyncDrawable);//下载前的显示
			}
			task.execute(data);
		}

	}
	
	public void loadImage(int num, ImageView imageView) {
		if (mImageWorkerAdapter != null) {
			loadImage(mImageWorkerAdapter.getItem(num), imageView);
		} else {
			throw new NullPointerException("Data not set, must call setAdapter() first.");
		}
	}
	/**
	 * 处理图片
	 * 
	 * @param data
	 *            根据这个信息
	 * @return 一个图片
	 */
	protected abstract Bitmap processBitmap(Object data);
	
	/**
	 * 设置缓存回调
	 * @param cacheCallback
	 */
	public void setImageCache(ImageCache cacheCallback) {
		mImageCache = cacheCallback;
	}
	
	public static boolean cancelPotentialWork(Object data, ImageView imageView) {
		final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

		if (bitmapWorkerTask != null) {
			final Object bitmapData = bitmapWorkerTask.data;
			if (bitmapData == null || !bitmapData.equals(data)) {
				bitmapWorkerTask.cancel(true);
			} else {
				// 已有相同任务正在处理
				return false;
			}
		}
		return true;
	}
	
	/**
	 * 处理异步下载图片类
	 * @author huangrongcai
	 *
	 */
	public class BitmapWorkerTask extends AsyncTask<Object, Void, Bitmap> {
		private Object data;
		private final WeakReference<ImageView> imageViewReference;

		public BitmapWorkerTask(ImageView imageView) {
			this.imageViewReference = new WeakReference<ImageView>(imageView);
		}

		@Override
		protected Bitmap doInBackground(Object... params) {
			// TODO 后台下载处理
			
			data = params[0];
			Bitmap bitmap = null;
			if (bitmap == null) {
				bitmap = processBitmap(params[0]);
			}
			//图片缓存
			if (bitmap != null && mImageCache != null) {
				//验证文件完性，是不是完整一张图片
				final String dataString = String.valueOf(data);
//				mImageCache.addBitmapToCache(dataString, bitmap);
			}
			
			return bitmap;
		}

		@Override
		protected void onPostExecute(Bitmap bitmap) {
			final ImageView imageView = getAttachedImageView();
			ThreadMap.remove(imageView);
			if (bitmap != null) {
				setImageBitmap(imageView, bitmap);
			}
		}

		/**
		 * 获取被软引保存的图片视图对象
		 * @return 当前下载任务的ImageView,否则返回null;
		 */
		public ImageView getAttachedImageView() {
			final ImageView imageView = imageViewReference.get();
			final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
			if (this == bitmapWorkerTask) {
				return imageView;
			}
			return null;
		}

	}
	/**
	 * 默认图片,需要在加载图片之前之设置此项。才可以观看到效果
	 * @param emptyPhoto
	 */
	protected void setLoadingImage(int emptyPhoto) {
		// 加载时显示默认图片，此图需要复用
		mLoadingBitmap = BitmapFactory.decodeResource(mContext.getResources(), emptyPhoto);
		
	}
	/**
	 * @param imageView 任意的ImageView 实例
	 * @return 取回与imageView 有关联的异步任务。如没有相关任务则返回null;
	 */
	private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
		if (imageView != null) {
			final Drawable drawable = imageView.getDrawable();
			if (drawable instanceof AsyncDrawable) {
				final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
				return asyncDrawable.getBitmapWorkerTask();
			}
		}
		return null;
	}

	/**
	自定义绘图将连接到imageView工作正在进行时。
	包含对实际工作者的任务，这样就可以停止一个新绑定是必需的，
	并确保只有上次启动辅助进程可以绑定其结果，独立完成订单。
	 */
	private static class AsyncDrawable extends BitmapDrawable {
		private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

		public AsyncDrawable(Resources res, Bitmap bitmap,BitmapWorkerTask bitmapWorkerTask) {
			super(res, bitmap);

			bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(
					bitmapWorkerTask);
		}

		public BitmapWorkerTask getBitmapWorkerTask() {
			return bitmapWorkerTaskReference.get();
		}
	}

	/**
	 * 设置图片显示
	 * 
	 * @param imageView 图片显示组件
	 * @param bitmap 被显示的图片对象
	 */
	public void setImageBitmap(ImageView imageView, Bitmap bitmap) {
		// TODO 可以在显示给于动画效果
		if (imageView != null && bitmap != null) {
			imageView.setImageBitmap(bitmap);
		}

	}
	

	public ImageCache getImageCache() {
		return mImageCache;
	}
	/**
	 * Set the simple adapter which holds the backing data.
	 * 
	 * @param adapter
	 */
	public void setAdapter(ImageWorkerAdapter adapter) {
		mImageWorkerAdapter = adapter;
	}

	/**
	 * Get the current adapter.
	 * 
	 * @return
	 */
	public ImageWorkerAdapter getAdapter() {
		return mImageWorkerAdapter;
	}

	/**
	 * A very simple adapter for use with ImageWorker class and subclasses.
	 */
	public static abstract class ImageWorkerAdapter {
		public abstract Object getItem(int num);
		public abstract int getSize();
	}
	
	/**
	 * 设置暂停线程任务 参照：ImageWork
	 * @param b true 取消线程，flase，不做处理
	 */
	public void pauseTasks(boolean b) {
		int i= 0;
		// TODO 线程暂停
		if(b){
			for(Entry<ImageView, BitmapWorkerTask> entry: ThreadMap.entrySet()){
				entry.getValue().cancel(true);
				i++;
			}
		}else{
			//线程恢复
			for(Entry<ImageView, BitmapWorkerTask> entry: ThreadMap.entrySet()){
				Log.i(TAG, entry.toString());
				i++;
			}
		}
		Log.i(TAG, "线程数量"+i);
	}
}
